package com.liu.config;

import com.liu.domain.base.BaseResult;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 全局捕获异常
 *
 * @author: GLL
 */
@Slf4j
//@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final String BAD_REQUEST_MSG = "请求参数错误：";

    /**
     * 参数校验异常
     * 1 form data方式调用接口校验失败抛出的异常
     */
    @ExceptionHandler(value = BindException.class)
    public BaseResult handleBindException( BindException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        StringBuilder sb = new StringBuilder();
        for (FieldError fieldError : fieldErrors) {
            sb.append(fieldError.getDefaultMessage()).append("；");
        }

        log.error("参数校验异常: {}",sb);
        return BaseResult.error(BAD_REQUEST_MSG + sb);
    }

    // 2 json 请求体调用接口校验失败抛出的异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public BaseResult methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        StringBuilder sb = new StringBuilder();
        for (FieldError fieldError : fieldErrors) {
            sb.append(fieldError.getDefaultMessage()).append("；");
        }

        log.error("参数校验异常: {}",sb);
        return BaseResult.error(BAD_REQUEST_MSG + sb);
    }
    // 3 处理单个参数校验失败抛出的异常
    @ExceptionHandler(ConstraintViolationException.class)
    public BaseResult constraintViolationExceptionHandler(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        String err = constraintViolations.stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining("；"));

        log.error("参数校验异常: {}",err);

        return BaseResult.error(BAD_REQUEST_MSG + err);
    }


    /**
     * 通用异常
     */
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public BaseResult handleException(Exception e) {
        log.error("全局异常", e);
        return BaseResult.error("系统异常");
    }

    /**
     * 拦截参数异常
     *
     * @param illegalArgumentException 参数异常校验
     * @return 抛出异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public BaseResult handleIllegalArgumentException(IllegalArgumentException illegalArgumentException) {
        log.error("非法参数异常",illegalArgumentException);
        return BaseResult.error(illegalArgumentException.getMessage());
    }

}
